using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

namespace NUtil.lists {
    public class ListEquals {
        private static Type getElementType(IList source) {
            return source[0].GetType();
        }

        public bool ListEqual(IList list1, IList list2, bool orderMatters) {
            bool areEqual = true;

            if ((list1 != null) && (list2 != null)) {
                if (list1.Count != list2.Count) {
                    areEqual = false;
                }
                else {
                    areEqual = orderMatters
                                   ? compareElementsOrderMatters(list1, list2)
                                   : compareElementsOrderDoesNotMatter(list1, list2);
                }
            }
            else {
                if (!((list1 == null) && (list2 == null))) {
                    areEqual = false;
                }
            }
            return areEqual;
        }

        private bool compareElementsOrderMatters(IList list1, IList list2) {
            bool areEqual = true;
            for (int i = 0; i < list1.Count; i++) {
                if (!Object2AreEqual(list1[i], list2[i])) {
                    areEqual = false;
                    break;
                }
            }
            return areEqual;
        }

        private bool compareElementsOrderDoesNotMatter(IList list1, IList list2) {
            bool areEqual = true;
            for (int i = 0; i < list1.Count; i++) {
                Object obj1 = list1[i];
                Object obj2 = list2[i];
                if (!list2.Contains(obj1)) {
                    areEqual = false;
                    break;
                }
                if (!list1.Contains(obj2)) {
                    areEqual = false;
                    break;
                }
            }
            return areEqual;
        }

        private bool Object2AreEqual(object obj1, object obj2) {
            if (obj1 == null && obj2 == null) {
                return true;
            }
            else {
                if (obj1 != null && obj2 != null) {
                    return obj1.Equals(obj2);
                }
                else {
                    return false;
                }
            }
        }
    }
}